home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / hardware / summa / README.streams < prev    next >
Encoding:
Text File  |  1994-08-02  |  14.8 KB  |  316 lines

  1.  
  2.       -----------------------------------------------------------------
  3.       README for ~4Dgifts/examples/devices/input streams modules source
  4.       -----------------------------------------------------------------
  5.  
  6.  
  7.  
  8.                                   OVERVIEW
  9.  
  10.          The streams modules convert a device-specific data-stream
  11.          into a device-independent format that the X server reads.
  12.          This is exactly what the old device daemons used to do.  
  13.          The only difference is that they are "in-line" (i.e. now 
  14.          there's no need to do context switching, etc.--everything 
  15.          happens in streams).
  16.  
  17.  
  18.                          
  19.  
  20.  
  21.                          INPUT DEVICES IN IRIX 5.1
  22.  
  23.      First, a discussion of the way input devices work under IRIX 5.1.
  24.  
  25.     The X server reads fixed format events directly from a shared memory
  26.     queue in the kernel.   Each input device has a streams module
  27.     in the kernel that formats device specific data into the structure
  28.     which the X server uses and passes the result up to a multiplexor
  29.     stream head which timestamps each event and adds it to the queue.
  30.     The stream head also moves the cursor if the event is of type 
  31.     QE_PTR_EVENT and the device is allowed to change the cursor.
  32.  
  33.  
  34.                              +-------------+
  35.                              |   X Server  |
  36.                              +-------------+
  37.                                     |
  38.                         Shared Memory Input Queue
  39.              All events (going up) are of type struct shmqevent
  40.                   All events (going up) are time stamped
  41.                                     |
  42.                   Server issues generic input device ioctls 
  43.                             (defined in idev.h)
  44.                    which are passed down to the appropriate 
  45.                                 device module
  46.                                     |
  47.                               +-----------+
  48.                               |   shmiq   |
  49.                               +-----------+
  50.                               /     |      \
  51.                              /      |       \
  52.                          Streams Message Buffers
  53.                   All events are of type struct shmevent
  54.                      Events are not timestamped yet
  55.                           /         |          \
  56.                    +--------+    +-------+   +---------+
  57.                    |  mouse |    | sball |   | <other> |
  58.                    +--------+    +-------+   +---------+
  59.                       /             |             \
  60.               mouse specific    spaceball      data stream
  61.                 data stream    specific data  specific to other device
  62.                      /            stream            \
  63.           +------------------+      |        +--------------------+
  64.           | /dev/input/mouse |      |        | /dev/input/<other> |
  65.           +------------------+      |        +--------------------+
  66.                          +----------------------+
  67.                          | /dev/input/spaceball |
  68.                          +----------------------+
  69.  
  70.  
  71.     The shmiq assigns device minor numbers and a unique index to each newly 
  72.     opened streams module.   Each module must remember both values and store 
  73.     them in each message to validate the message to shmiq.  The shmiq will 
  74.     not deliver a message with an incorrect index or devminor in its 
  75.     shmiqlinkid.   
  76.     
  77.     Don't worry too much about this -- helper functions in idev.c take care 
  78.     of most of the interactions with the stream head for you.
  79.     
  80.     To the server, all devices look alike.   They respond to ioctls defined
  81.     in idev.h and generate messages in shmqevent format.   A shmqevent
  82.     is defined in shmiq.h as follows:
  83.     
  84.     struct shmqdata {
  85.             unsigned char device;
  86.             unsigned char type;
  87.             unsigned char which;
  88.             unsigned char flags;
  89.         union {
  90.         long int pos ;        /* big event data */
  91.         short ptraxis[2] ;    /* event data for PTR events */
  92.         } un;
  93.     };
  94.     
  95.     struct shmiqlinkid {
  96.             short int devminor;
  97.             short int index;
  98.     };
  99.     struct shmqevent {
  100.             union {
  101.                 long int time;
  102.                 struct shmiqlinkid id;
  103.             } un;
  104.             struct shmqdata data;
  105.     };
  106.     
  107.  
  108.     For each event, the device specific module fills in:
  109.          un.devminor = the devminor assigned to the device by shmiq
  110.          un.index    = the index assigned to the device by shmiq
  111.          data.device = the index assigned to the device by shmiq
  112.                        (again, identifies the device to the server -- 
  113.                         shmiq clobbers the un.* values with a timestamp)
  114.          data.type   = the type of the event.  The only event types 
  115.                        currently defined are:
  116.                        QE_BTN_EVENT -- button changed state
  117.                        QE_VAL_EVENT -- valuator moved
  118.                QE_PTR_EVENT -- one (or more) valuators which are
  119.                     controlling the cursor moved.
  120.          data.which  = the index (0 based) of the button or valuator
  121.                        which changed state.
  122.          data.flags  = For events of type QE_BTN_EVENT:
  123.                            QE_BTN_DOWN is set if the button was pressed
  124.                            0 if the button was released
  125.                        For events of type QE_VAL_EVENT:
  126.                            QE_MORE_EVENTS is set if more valuator events 
  127.                                follow this event.   For example, the 
  128.                                spaceball can generate up to six events at 
  129.                                a time.  All events save the last have the 
  130.                                QE_MORE_EVENTS bit set in data.flags.
  131.                            QE_RESPONSE is set if the event was generated 
  132.                                in response to a request by the X server 
  133.                                -- i.e.  an IDEV_SETVALUATORS or 
  134.                                IDEV_CHANGEVALUATORS ioctl.
  135.                            QE_CLAMPED is set if the device generated an 
  136.                                event outside the range set for the device 
  137.                                by the X server.   The event should be 
  138.                                clamped to the specified range and the 
  139.                                QE_CLAMPED event bit set.   
  140.             For events of type QE_PTR_EVENT:
  141.                QE_GEN_PTR_X -- this event reports a value for
  142.                 the X axis.
  143.                QE_GEN_PTR_Y -- this event reports a value for
  144.                 the Y axis.
  145.                QE_X_CLAMPED -- the X value in this event was
  146.                 clamped.
  147.                QE_Y_CLAMPED -- the Y value in this event was
  148.                 clamped.
  149.          un.data.pos  = For events of type QE_VAL_EVENT, the un.data.pos 
  150.                             field contains the new valuator value.
  151.                         For events of type QE_BTN_EVENT, the contents of 
  152.                             the un.data.pos field are undefined.
  153.      un.data.ptraxis = For events of type QE_PTR_EVENT, un.data.ptraxis[0]
  154.                 contains an X value (if the QE_GEN_PTR_X flag
  155.                 is set) and the un.data.ptraxis[1] field contains
  156.                 a value for Y (if the QE_GEN_PTR_Y flag is set).
  157.     
  158.     The file idev.c in the io directory contains helper functions 
  159.     which greatly simplify the process of adding support for an input
  160.     device.    If you set up your data structures correctly (using XXX.c
  161.     as a template), the functions in idev.c handle shmiq M_PROTO
  162.     events, format and forward events and deal with most device trivia.
  163.     You should be able to modify XXX.[ch] (mostly using global replace 
  164.     and deleting inappropriate functions) and then write 2-4 functions:
  165.     You must write:
  166.         an open function which initializes the data structures that 
  167.         idev.c expects.  Do not write modify the device in the open
  168.         function.
  169.         an intr function which accepts strings of bytes from the devices
  170.             and calls idev functions to generate events when appropriate.
  171.         You should call idevGenPtrEvent(s) and idevGenBtnEvent(s) (see
  172.         idev.h) to generate the actualy events.   These functions will
  173.         handle the various modes and generate appropriate event types 
  174.         for you.
  175.     You might need to write:
  176.     an init_device function which changes line settings and writes any
  177.         initialization information to the device.
  178.     an other_control function which supports device-specific configurations
  179.         which are not handled by another ioctl from idev.h.
  180.     
  181.     The X server assumes all device events are absolute device 
  182.     coordinates.  The shmiq uses QE_PTR_EVENTS events to control the 
  183.     cursor -- passing relative coordinates up to shmiq may cause bizarre 
  184.     cursor tracking.  You should generate absolute values whenever 
  185.     possible.
  186.  
  187.     
  188.                    SUPPORTING A NEW DEVICE IN IRIX 5.1
  189.     
  190.         The files io/XXX.c and sys/XXX.h provide a template for a device
  191.     module implementation.   Copy these files and modify them as 
  192.     appropriate for your device.   The generic device interface defines 
  193.     a number of ioctls for each device -- your device need not support 
  194.     inappropriate ioctls (e.g. the keyboard doesn't support any ioctls 
  195.     which query or change valuator state or characteristics).  
  196.     
  197.         You should not initialize the device at open time -- the serial
  198.     line settings may be incorrect when the device is opened.   The X 
  199.     server might open the device many times to get information without
  200.     ever actually using the device.  Before it actually uses the device 
  201.     for the first time, it calls IDEVINITDEVICE.  If you need to set up 
  202.     your device, do so when IDEVINITDEVICE is called.   Your module should
  203.     discard any data read from the device before INITDEVICE is called.
  204.     
  205.     
  206.                         About IDEVGETDEVICEDESC
  207.     
  208.     All devices must support the IDEVGETDEVICEDESC ioctl.   If the
  209.     hasKeymap field is 1 in the returned structure, the X server will
  210.     generate KeyPress and KeyRelease events.    If hasKeymap is 0,
  211.     the X server generates ButtonPress and ButtonRelease.
  212.     
  213.     Normally, the server tries to open each file in /dev/input and uses a 
  214.     module with the name of the file (e.g. it opens /dev/input/mouse and 
  215.     I_PUSHes the "mouse" module).   If the file name contains a dash, the 
  216.     server uses the device name before the dash as the module name, and 
  217.     the first 16 characters after the dash as an option string.  Before
  218.     initializing a device (with IDEVINITDEVICE), the X server issues
  219.     an IDEVOTHERCONTROL ioctl (see below) with the name "/nameopt/" and value
  220.     of the characters after the '-' in the device name.
  221.     For example, the X server opens /dev/input/sball-dials, I_PUSHes 
  222.     the "sball" module, issues an IDEVOTHERCONTROL ioctl with 
  223.     name="/nameopt/" and value="dials," queries the device and finally 
  224.     issues an IDEVINITDEVICEIOCTL and reads events from the device.
  225.     If your device can be configured several ways, look for a "/nameopt/"
  226.     option to modify the device characteristics.   The X server passes
  227.     the option before querying the device so you can completely change
  228.     the characteristics of your device invisibly (to the X server).
  229.     
  230.  
  231.                        USING A DEVICE IN IRIX 5.1
  232.  
  233.     Use the X input extension to control devices in IRIX 5.1.   All
  234.     devices supported by the GL in IRIX releases before 5.1 will 
  235.     continue to work (using qdevice), but there is no straightforware 
  236.     way to add new devices to the GL at present.
  237.     
  238.     If you need device controls that the input extension does not 
  239.     provide, you can use the IDEVOTHERCONTROL ioctl.  This ioctl takes
  240.     an idevOtherControl structure which has a name (up to IDEV_CTRL_NAME_LEN
  241.     characters) and a value (up to IDEV_CTRL_DATA_LEN).   The IDEVOTHERCONTROL
  242.     option returns the contents of the idevOtherControl to the X server so
  243.     you can return information by changing the structure in place.
  244.     To issue an IDEVOTHERCONTROL from an X client, use the XSGIDeviceControl
  245.     function:
  246.     Bool XSGIDeviceControl( dpy, devID, name, value )
  247.     Display *dpy;
  248.     int     devID;
  249.     char     *name;
  250.     char     *value;
  251.     If "name" is not one of the controls used by the server itself, the
  252.     creates an idevOtherControl structure, fills it in with the name and 
  253.     value from the request (truncating as necessary) and issues the 
  254.     IDEVOTHERCONTROL ioctl to the device.  The example spaceball driver 
  255.     supports a few other controls -- look in sball.c for examples.
  256.  
  257.     You should use a prefix for your device controls as the X server uses some
  258.     non-prefixed controls.
  259.  
  260.     If you need to query the device for information that isn't available 
  261.     through the X input extension, you can use the IDEVOTHERQUERY ioctl.
  262.     To issue an IDEVOTHERQUERY ioctl from an X client, use the XSGIDeviceQuery
  263.     function:
  264.     Bool XSGIDeviceQuery( dpy, devID, name, rtrn )
  265.     Display *dpy;
  266.     int     devID;
  267.     char     *name;
  268.     char     *value; /* OUT */
  269.     If "name" is not one of the queries used by the X server, the server
  270.     creates an idevOtherQuery structure and issues an IDEVOTHERQUERY 
  271.     to the device module.   If the ioctl succeeds, the server returns
  272.     24 bytes of data from the device module to the client.
  273.  
  274.     If the server or device module answers a query, XSGIDeviceQuery returns
  275.     TRUE and rtrn contains 24 bytes of data.   If neither the server nor
  276.     the device module recognize the query, XSGIDeviceQuery returns FALSE
  277.     and the contents of rtrn are undefined.
  278.     
  279.  
  280.                 ADDING A NEW DEVICE MODULE TO THE SYSTEM
  281.  
  282.     Here's what you have to do to add a device module to an IRIX 5.1 
  283.     system:
  284.     
  285.     Compile your streams module as shown by the Makefile in the io
  286.     subdirectory.  Add the resulting .o file to /var/sysgen/boot.
  287.     
  288.     Copy /var/sysgen/master.d/dial to /var/sysgen/master.d/<device>
  289.     where <device> is the name of your device.   Edit your new file in 
  290.     master.d and change all occurences of "dial" or "DIAL" to the name 
  291.     of your device.
  292.     
  293.     Edit /var/sysgen/system/gfx.sm, and add the line "USE: <device>"
  294.     (the name of your device should be the name of the file you added 
  295.     to master.d).
  296.  
  297.     If the 'd' and 'R' flags are specified in the master.d file
  298.     the driver will be dynamically loaded into the running kernel
  299.     on each system boot.  The driver can also be dynamically loaded
  300.     and unloaded with the lboot command.  See mload(4), ml(1m) and
  301.     lboot(1m) for more information on dynamic loading.
  302.     
  303.     If the module is not dynamically loaded, you need to rebuild a
  304.     kernel using autoconfig(1M).
  305.     
  306.     Link the serial device to which your device is connected to 
  307.     /dev/input/<device> (<device> is the name of your device, again).
  308.     
  309.     When you reboot, the X server should find and use your device.
  310.     Consult the documentation for the Input Extension to the X Window 
  311.     System for the details of using an X extension device.
  312.     
  313.     The test directory contains (minimal) user-level streams simulation
  314.     so you can debug your device module without re-linking your kernel.
  315.     See test/README for details.
  316.